#pragma once
//#include <map>
//#include <string>
#include "..\dxstdafx.h"
#include "..\lib\container\List.h"

typedef unsigned int uint32;

namespace ds {

// ------------------------------------------------------------
// The list of defined constants that the ResManager supports
// ------------------------------------------------------------
const int RS_NONE               = 0;
const int RS_MATERIAL           = 1;
const int RS_TEXTURE            = 2;
const int RS_SHADER             = 3;
const int RS_SOUND              = 4;
const int RS_MESH               = 5;
const int RS_RENDERTARGET       = 6;
const int RS_FONT               = 7;
const int RS_VERTEX_DECLARATION = 8;
const int RS_BITMAP_FONT        = 9;
const int RS_INVALID            = 15; // this is the maximum!
// ------------------------------------------------------------
// The ResourceHandle
// ------------------------------------------------------------
struct ResourceHandle {
	ResourceHandle() : m_Index(0) , m_Type(0) {}
	ResourceHandle(int index,int type) : m_Index(index) , m_Type(type) {}
	bool operator==(const ResourceHandle &other) const;
	bool operator!=(const ResourceHandle &other) const;
	uint32 m_Index : 28;
	uint32 m_Type : 4;
};

inline bool ResourceHandle::operator==(const ResourceHandle &other) const {
	if ( m_Index == other.m_Index && m_Type == other.m_Type ) {
		return true;
	}
	return false;
}
inline bool ResourceHandle::operator!=(const ResourceHandle &other) const {
	if ( m_Index != other.m_Index || m_Type != other.m_Type ) {
		return true;
	}
	return false;
}

class Material;
class Texture;
class Sound;
class Shader;
class RenderTarget;
class VertexDeclaration;
class BitmapFont;
// ------------------------------------------------------------
// The ResManager 
// ------------------------------------------------------------
class ResManager {

struct NameMapping {
	IdString hash;
	ResourceHandle handle;
	char name[128];
};

typedef List<NameMapping> NameList;

public:
	ResManager();
	~ResManager();
	// basic
	ResourceHandle& findByName(const char* name,int type);
	bool contains(const char* name);
	bool contains(const char* name,int type);
	// bitmap font
	ResourceHandle createBitmapFont(const char* name,uint32 startChar,uint32 charHeight,uint32 startX,uint32 startY,uint32 textureSize);	
	BitmapFont* getBitmapFont(ResourceHandle handle);
	BitmapFont* getBitmapFontByName(const char* name);
	// Textures
	ResourceHandle createTexture(const char* name,const char* fileName,int width,int height);	
	ResourceHandle createTexture(const char* name,const char* fileName);	
	ResourceHandle createTexture(const char* name,Texture* texture);	
	Texture* getTexture(ResourceHandle handle);
	Texture* getTextureByName(const char* name);
	// Materials
	ResourceHandle createMaterial();
	ResourceHandle createMaterial(const char* name);
	ResourceHandle createMaterial(const char* name,ResourceHandle textureHandle,bool useAlpha = false);
	ResourceHandle createMaterial(const char* name,const char* textureName,bool useAlpha = false);
	Material* getMaterial(ResourceHandle handle);
	Material* getMaterialByName(const char* name);
	// sound
	ResourceHandle loadSound(const char* name,const char* fileName);
	Sound* getSound(ResourceHandle handle);
	Sound* getSoundByName(const char* name);
	// shader
	ResourceHandle loadShader(const char* name,const char* fileName,const char* techName);
	ResourceHandle addShader(const char* name,Shader* shader);
	void assignShader(const char* shaderName,const char* materialName);
	void assignShader(ResourceHandle shaderHandle,ResourceHandle materialHandle);
	Shader& getShaderByName(const char* name);
	Shader& getShader(ResourceHandle shaderHandle);
	// render targets
	ResourceHandle createRenderTarget(int index,const char* materialName);
	RenderTarget* getRenderTarget(ResourceHandle handle);
	// fonts
	ResourceHandle loadFont(const char* name,const char* fontName,int size,bool bold = false);
	ResourceHandle loadFont(const char* name,const char* fileName,const char* fontName,int size,bool bold = false);
	ID3DXFont* getFont(ResourceHandle handle);
	ID3DXFont* getFont(const char* name);
	// vertex declarations
	ResourceHandle createVertexDeclaration(const char* name);
	VertexDeclaration* getVertexDeclaration(const char* name);
	VertexDeclaration* getVertexDeclaration(ResourceHandle handle);
	// stuff
	void debug();
private:
	//
	void addName(const char* name,ResourceHandle handle);	
	std::string translateType(ResourceHandle handle);
	//
	List<Material*> m_Materials;
	List<Texture*> m_Textures;
	List<Sound*> m_Sounds;
	List<Shader*> m_Shaders;
	List<ID3DXFont*> m_Fonts;
	List<BitmapFont*> m_BitmapFonts;
	List<VertexDeclaration*> m_VertexDeclarations;
	List<RenderTarget*> m_RenderTargets;
	NameList m_NameList;
};

}

